package com.cskaoyan._01datasecurity;

/**
 * @description:
 * @author: 景天
 * @date: 2023/2/22 9:16
 **/
/*
多线程仿真如下场景：
假设A电影院正在上映某电影，该电影有100张电影票可供出售，
现在假设有3个窗口售票。请设计程序模拟窗口售票的场景。
分析:
有3个窗口售票 ---> 3个线程
3个窗口共同售卖100张票----> 3个线程共享了100这个数据

使用Runnable方式
 */
public class Demo2 {
    public static void main(String[] args) {
        // 创建3个窗口 3个线程
        SellWindow2 sellWindow2 = new SellWindow2();
        Thread t1 = new Thread(sellWindow2);
        Thread t2 = new Thread(sellWindow2);
        Thread t3 = new Thread(sellWindow2);
        t1.setName("A窗口");
        t2.setName("B窗口");
        t3.setName("C窗口");

        // start方法启动
        t1.start();
        t2.start();
        t3.start();
    }
}

class SellWindow2 implements Runnable{
    // 定义票
    int tickets = 100;
    // run
    @Override
    public void run() {
       // 模拟卖票的过程
        // 分析为什么出现重复的票
        // 假设此时tickets = 100
        // 假设A线程先执行,此时tickets =100
        // 假设B抢到了CPU的执行权,B执行,此时tickets =100
        // 假设C抢到了CPU的执行权,C执行,此时tickets =100

        // 为什么出现不存在的票?
        // 假设此时tickets = 1
        // 假设A抢到了CPU的执行权,A执行 tickets = 1
        // 假设B抢到了CPU的执行权,B执行 tickets = 1
        // 假设C抢到了CPU的执行权,C执行 tickets = 1
        while (true) {
            // 卖之前进行判断
            if (tickets > 0) {
                // A线程进入到if 睡眠
                // B线程进入到if 睡眠
                // C线程进入到if 睡眠
                // 模拟网络时延
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


                System.out.println(Thread.currentThread().getName() + "卖了第"
                        + (tickets--) + "张票");
                // tickets-- 分为几步?
                // 1.取值 2.-1 3.赋值
                // 假设A线程醒来抢到了CPU的执行权,A继续执行 取值100 没来得及-1
                // 假设B线程醒来抢到了CPU的执行权,B继续执行 取值100 没来得及-1
                // 假设C线程醒来抢到了CPU的执行权,C继续执行 取值100 没来得及-1


                //假设A线程醒来抢到了CPU的执行权,A继续执行,取值1
                // A窗口卖了第1张票 还剩0
                // B线程醒来抢到了CPU的执行权,B继续执行, 取值0
                // B卖了第0张票, 还剩-1
                // C线程醒来抢到了CPU的执行权,C继续执行  取值-1
                // C卖了第-1张票 还剩-2

            }
        }
    }
}